package tree;

/**
 * 450. 删除二叉搜索树中的节点
 *
 * 给定一个二叉搜索树的根节点 root 和一个值 key，删除二叉搜索树中的key对应的节点，并保证二叉搜索树的性质不变。返回二叉搜索树（有可能被更新）的根节点的引用。
 *
 * 一般来说，删除节点可分为两个步骤：
 *
 * 首先找到需要删除的节点；
 * 如果找到了，删除它。
 */
public class DeleteNodeInBST_450 {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) {
            return null;
        }
        if (root.val == key) {
            if (root.left == null) {
                return root.right;
            } else if (root.right == null) {
                return root.left;
            } else {
                // 如果左子树右子树都存在，从左子树中找到最大节点作为根节点
                TreeNode left = root.left;
                while (left.right != null) {
                    left = left.right;
                }
                // 将根节点的右子树转移到根节点左子树最大值节点的右子树上
                left.right = root.right;
                // 用左子树替换根节点，从而删除根节点，赋值为null是没用的
                root = root.left;
            }
        } else if (root.val < key) { // 如果目标节点大于当前节点值，则去右子树中删除；
            root.right = deleteNode(root.right, key);
        } else { // 如果目标节点小于当前节点值，则去左子树中删除；
            root.left = deleteNode(root.left, key);
        }

        return root;
    }
}
